(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define('simple-module', ["jquery"], function ($) {
            return (root.returnExportsGlobal = factory($));
        });
    } else if (typeof exports === 'object') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like enviroments that support module.exports,
        // like Node.
        module.exports = factory(require("jquery"));
    } else {
        root['SimpleModule'] = factory(jQuery);
    }
}(this, function ($) {

    var Module,
        __slice = [].slice;

    Module = (function () {
        Module.extend = function (obj) {
            var key, val, _ref;
            if (!((obj != null) && typeof obj === 'object')) {
                return;
            }
            for (key in obj) {
                val = obj[key];
                if (key !== 'included' && key !== 'extended') {
                    this[key] = val;
                }
            }
            return (_ref = obj.extended) != null ? _ref.call(this) : void 0;
        };

        Module.include = function (obj) {
            var key, val, _ref;
            if (!((obj != null) && typeof obj === 'object')) {
                return;
            }
            for (key in obj) {
                val = obj[key];
                if (key !== 'included' && key !== 'extended') {
                    this.prototype[key] = val;
                }
            }
            return (_ref = obj.included) != null ? _ref.call(this) : void 0;
        };

        Module.connect = function (cls) {
            if (typeof cls !== 'function') {
                return;
            }
            if (!cls.pluginName) {
                throw new Error('Module.connect: cannot connect plugin without pluginName');
                return;
            }
            cls.prototype._connected = true;
            if (!this._connectedClasses) {
                this._connectedClasses = [];
            }
            this._connectedClasses.push(cls);
            if (cls.pluginName) {
                return this[cls.pluginName] = cls;
            }
        };

        Module.prototype.opts = {};

        function Module(opts) {
            var cls, instance, instances, name, _base, _i, _len;
            this.opts = $.extend({}, this.opts, opts);
            (_base = this.constructor)._connectedClasses || (_base._connectedClasses = []);
            instances = (function () {
                var _i, _len, _ref, _results;
                _ref = this.constructor._connectedClasses;
                _results = [];
                for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                    cls = _ref[_i];
                    name = cls.pluginName.charAt(0).toLowerCase() + cls.pluginName.slice(1);
                    if (cls.prototype._connected) {
                        cls.prototype._module = this;
                    }
                    _results.push(this[name] = new cls());
                }
                return _results;
            }).call(this);
            if (this._connected) {
                this.opts = $.extend({}, this.opts, this._module.opts);
            } else {
                this._init();
                for (_i = 0, _len = instances.length; _i < _len; _i++) {
                    instance = instances[_i];
                    if (typeof instance._init === "function") {
                        instance._init();
                    }
                }
            }
            this.trigger('initialized');
        }

        Module.prototype._init = function () {
        };

        Module.prototype.on = function () {
            var args, _ref;
            args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
            (_ref = $(this)).on.apply(_ref, args);
            return this;
        };

        Module.prototype.one = function () {
            var args, _ref;
            args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
            (_ref = $(this)).one.apply(_ref, args);
            return this;
        };

        Module.prototype.off = function () {
            var args, _ref;
            args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
            (_ref = $(this)).off.apply(_ref, args);
            return this;
        };

        Module.prototype.trigger = function () {
            var args, _ref;
            args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
            (_ref = $(this)).trigger.apply(_ref, args);
            return this;
        };

        Module.prototype.triggerHandler = function () {
            var args, _ref;
            args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
            return (_ref = $(this)).triggerHandler.apply(_ref, args);
        };

        Module.prototype._t = function () {
            var args, _ref;
            args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
            return (_ref = this.constructor)._t.apply(_ref, args);
        };

        Module._t = function () {
            var args, key, result, _ref;
            key = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
            result = ((_ref = this.i18n[this.locale]) != null ? _ref[key] : void 0) || '';
            if (!(args.length > 0)) {
                return result;
            }
            result = result.replace(/([^%]|^)%(?:(\d+)\$)?s/g, function (p0, p, position) {
                if (position) {
                    return p + args[parseInt(position) - 1];
                } else {
                    return p + args.shift();
                }
            });
            return result.replace(/%%s/g, '%s');
        };

        Module.i18n = {
            'zh-CN': {}
        };

        Module.locale = 'zh-CN';

        return Module;

    })();


    return Module;


}));
